/*
 * @(#)EmailReceiverImpl.java
 *
 * Copyright (c) 2005 DCIVision Ltd
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of DCIVision
 * Ltd ("Confidential Information").  You shall not disclose such Confidential
 * Information and shall use it only in accordance with the terms of the license
 * agreement you entered into with DCIVision Ltd.
 */

package com.dcivision.mail.core;

import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.Random;

import javax.mail.Address;
import javax.mail.BodyPart;
import javax.mail.FetchProfile;
import javax.mail.Flags;
import javax.mail.Message;
import javax.mail.Multipart;
import javax.mail.Part;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimePart;
import javax.mail.internet.MimeUtility;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.dcivision.dms.bean.EmailMessageToRule;
import com.dcivision.dms.dao.DmsDocumentDAObject;
import com.dcivision.framework.ApplicationException;
import com.dcivision.framework.DataSourceFactory;
import com.dcivision.framework.ErrorConstant;
import com.dcivision.framework.SessionContainer;
import com.dcivision.framework.SystemParameterConstant;
import com.dcivision.framework.SystemParameterFactory;
import com.dcivision.framework.TextUtility;
import com.dcivision.framework.Utility;
import com.dcivision.mail.bean.EmailAttachmentImpl;
import com.dcivision.mail.bean.EmailFolder;
import com.dcivision.mail.bean.EmailFolderImpl;
import com.dcivision.mail.bean.EmailMessage;
import com.dcivision.mail.bean.EmailMessageImpl;

/**
 EmailReceiverImpl.java
 
 This class about receive email.
 
 @author      Beyond.Qu
 @company     DCIVision Limited
 @creation date   14/01/2005
 @version     $Revision: 1.30.2.3 $
 */

public class EmailReceiverImpl extends EmailReceiver implements java.io.Serializable {
  
  public static final String REVISION = "$Revision: 1.30.2.3 $";
  
  private EmailFolderImpl folder;
  private Store store;
  private SessionContainer sessionContainer;
  private List mailList = new ArrayList();
  
  //if the email content format is html
  public static String GET_JOURNALING_EMAIL_FROM_EMAILCONTENT_FLAGE_BEGIN = "&lt;smtp:";
  public static String GET_JOURNALING_EMAIL_FROM_EMAILCONTENT_FLAGE_END = "&gt;";    
  
  public static final String EMAIL_CONTENT_TYPE_HTML = "html";
  public static final String EMAIL_CONTENT_TYPE_TXT = "txt";
  public static final String REPLACE_INVALID_CHAR = "-";    
  private String emailCharset = "";
  
  protected Log log = LogFactory.getLog(this.getClass().getName());  
  
  private EmailReceiverImpl(SessionContainer sessionContainer) {
    this.sessionContainer = sessionContainer;
  }
  
  public static EmailReceiverImpl newInstance(SessionContainer sessionContainer) {
    return new EmailReceiverImpl(sessionContainer);
  }
  
  /**
   * Method loadMailList()
   * 
   * @param host
   * @param name
   * @param password
   * @param protocol
   * @return mail list
   * @throws Exception
   */
  
  public List loadMailList(String host, String name, String password,String protocol) throws Exception {
    long startTime1 = 0;
    startTime1 = new java.util.Date().getTime();
    try {
      long startTime = 0;
      startTime = new java.util.Date().getTime();
      
      getMailFolder(host, name, password, protocol);
      folder.open(EmailFolderImpl.READ_ONLY);
      Message[] msg = folder.getMessages();
      FetchProfile profile = new FetchProfile();
      profile.add(FetchProfile.Item.ENVELOPE);
      
      startTime = new java.util.Date().getTime();
      for (int i = 0; i < msg.length; i++) {
        EmailMessageImpl emailMessage = EmailMessageImpl.newInstance();
        getMailPriority(emailMessage, msg[i]);
        mailList.add(emailMessage);
        msg[i].setFlag(Flags.Flag.DELETED,true);      
      }
      folder.fetch(msg, profile);
    } catch (Exception e) {
      throw e;
    } finally {
      closeStroreAndMailFolder();
    }
    
    return mailList;
  }
  
  /**
   * Method getMail()
   * 
   * @param host
   * @param name
   * @param password
   * @param protocol
   * @return messge array
   * @throws Exception
   */
  private void getMailFolder(String host, String name, String password,String protocol) throws Exception {
    Properties prop = System.getProperties();
    Session session = Session.getDefaultInstance(prop, null);
    session.setDebug(false);
    store = session.getStore(protocol);
    store.connect(host, name, password);
    folder = new EmailFolderImpl(store.getDefaultFolder().getFolder("INBOX"));
  }
  
  /**
   * Method getMail()
   * 
   * @param host
   * @param name
   * @param password
   * @param protocol
   * @return messge array
   * @throws Exception
   */
  private Message[] getMail(String host, String name, String password,String protocol) throws Exception {
    Properties prop = System.getProperties();
    Session session = Session.getDefaultInstance(prop, null);
    session.setDebug(false);
    store = session.getStore(protocol);
    store.connect(host, name, password);
    folder = new EmailFolderImpl(store.getDefaultFolder().getFolder("INBOX"));
    folder.open(EmailFolderImpl.READ_ONLY);
    
    Message[] msg = folder.getMessages();
    FetchProfile profile = new FetchProfile();
    profile.add(FetchProfile.Item.ENVELOPE);
    folder.fetch(msg, profile);
    return (msg);
    
  }
  
  /**
   * Method getMailPriority()
   * 
   * @param emailMessage
   * @param msg
   * @return @throws
   *         Exception
   */
  private void getMailPriority(EmailMessageImpl emailMessage, Message msg)throws Exception {
    try {  
    	List listMessageID = new ArrayList();
    	Connection conn=null;
      String sender ="";
      String to ="";
      String cc ="";      
      String subject = decodeText(msg.getSubject());                        
      if(Utility.isEmpty(subject)){       
        subject   = "(Not Subject)" ;
      }
      java.util.Date sendDate = msg.getSentDate();            
      try{
        sender = decodeText(parseArrayDataToString(msg.getFrom()));
      }catch(javax.mail.internet.AddressException addrex){
        log.error(addrex, addrex);
      }
      try{
        to = formatEmailAdress(decodeText(parseArrayDataToString(msg.getRecipients(Message.RecipientType.TO))));                
      }catch(javax.mail.internet.AddressException addrex){
        log.error(addrex, addrex);
      }
      try{
        cc = formatEmailAdress(decodeText(parseArrayDataToString(msg.getRecipients(Message.RecipientType.CC))));
      }catch(javax.mail.internet.AddressException addrex){
        log.error(addrex, addrex);
      }
      try{                
        emailMessage.setID(new Integer(msg.getMessageNumber()));
      }catch(Exception ex){
        log.error(ex, ex);
      }  
      try{
        conn = DataSourceFactory.getConnection();
      	DmsDocumentDAObject docDAO = new DmsDocumentDAObject(sessionContainer, conn);
      	listMessageID = docDAO.getAllExtRefList();
      	//conn.close();
      }catch(Exception e){
        log.error(e, e);
      }finally{
        try{conn.close();}catch(Exception ex){}finally{conn=null;}
      }
      
      //      emailMessage.setID(new Integer(msg.getMessageNumber()));
      sender = sender.replaceAll("\"",""  );
      to = to.replaceAll("\"",""  );
      cc = cc.replaceAll("\"",""  );
      emailMessage.setSubject(subject);
      emailMessage.setOriSubject(subject);      
      emailMessage.setSender(sender);
      emailMessage.setSendDate(sendDate);
      emailMessage.setTo(to);
      emailMessage.setCc(cc);
      emailMessage.setHaveAttachment(msg.isMimeType("multipart/mixed"));//if have attachment
      emailMessage.setIsHtml(msg.isMimeType("multipart/alternative"));//if email is html
      emailMessage.setIsHtml(msg.isMimeType("text/html"));//if email is html      
      emailMessage.setIsTextOnly(msg.isMimeType("text/plain"));//if email is html      
      emailMessage.setMessageID(((MimeMessage)msg).getMessageID());
      if(listMessageID.contains(((MimeMessage)msg).getMessageID())){
      	emailMessage.setIsSaved(true);
      }
      String pri[] = msg.getHeader("X-Priority");
      int priority = -1;
      if (pri == null) {
        priority = PRIORITY_NORMAL;
      } else {
        if (pri[0].indexOf("1") >= 0) {
          priority = PRIORITY_HIGHEST;
        } else if (pri[0].indexOf("2") >= 0) {
          priority = PRIORITY_HIGH;
        } else if (pri[0].indexOf("3") >= 0) {
          priority = PRIORITY_NORMAL;
        } else if (pri[0].indexOf("4") >= 0) {
          priority = PRIORITY_LOW;
        } else if (pri[0].indexOf("5") >= 0) {
          priority = PRIORITY_LOWEST;
        } else {
          priority = PRIORITY_NORMAL;
          for (int i = 0; i < pri.length; i++) {
            log.debug("UNKNOWN Priority: " + pri[i]);
          }
        }
      }
      emailMessage.setPriority(priority);
      emailMessage.setSize(msg.getSize());
    } catch (Exception ex) {
      log.error(ex, ex);
    }
  }
  
  /**
   * Method analyseMultipart() -- get the eamil attchment (MIME emails)
   * 
   * @param emailMessage
   * @param mpart
   * @return @throws
   *         Exception
   */
  public void analyseMultipart(EmailMessageImpl emailMessage, Multipart mpart)throws Exception {
    try {
      int count = mpart.getCount();
      for (int i = 0; i < count; i++) {
        Part part = mpart.getBodyPart(i);
        if (part.isMimeType("multipart/*")) {
          analyseMultipart(emailMessage, (Multipart) part.getContent());
        } else {
          if (part.isMimeType("TEXT/*")) {
            String fileName = null;
            try{
              fileName = part.getFileName();
            }catch(Exception e){
              
            }
              
            if (fileName == null) {                            
              if (part.isMimeType("TEXT/HTML")) {
                //if(emailMessage.getContent()==null){//barbin 2006-4-18
                  String contentText = decodeTextByEmailEncoding((String) part.getContent());                  
                  emailMessage.setContent(contentText);
                  emailMessage.setOriContent(contentText);
                  emailMessage.setEmailContentType(EmailMessage.EMAIL_CONTENT_TYPE_HTML);
                //}
              }else if (part.isMimeType("TEXT/PLAIN")) {
                //prevent TEXT/PLAIN overwrite TEXT/HTML
                if(emailMessage.getContent()==null){
                  String contentText = decodeTextByEmailEncoding((String) part.getContent());                  
                  emailMessage.setContent(contentText);
                  emailMessage.setOriContent(contentText);                  
                  emailMessage.setEmailContentType(EmailMessage.EMAIL_CONTENT_TYPE_TXT);                                
                }
              }
            } else {
              saveAttach(emailMessage, putAttachToCatchFile((BodyPart) part, emailMessage.getID().intValue(),emailMessage.getSubject()));
            }
          } else {
            String disp = part.getDisposition();
            String contentId = ((MimePart) part).getContentID();
            if (contentId != null) {
              EmailAttachmentImpl emailAttachment = putAttachToCatchFile((BodyPart) part, emailMessage.getID().intValue(),emailMessage.getSubject());
              saveAttach(emailMessage, emailAttachment);
              String baseUrl = com.dcivision.framework.SystemParameterFactory.getSystemParameter(com.dcivision.framework.SystemParameterConstant.APPLICATION_BASE_URL);
              String getContentUrl = baseUrl+ "/dms/emailArchiveGetImage?"+ "catchFileName="+ emailAttachment.getCatchFileName()+ "&attachFileName="+ emailAttachment.getAttachFileName();
              contentId = contentId.substring(1, contentId.length() - 1);
              String contentString = emailMessage.getContent().toString();
              String replacedContentString = TextUtility.replaceString(contentString, "cid:", getContentUrl);//barbin 2006-4-18
              emailMessage.setContent(replacedContentString);
              emailMessage.setEmailContentType(EmailMessage.EMAIL_CONTENT_TYPE_HTML);
            }else{
              saveAttach(emailMessage, putAttachToCatchFile((BodyPart) part, emailMessage.getID().intValue(),emailMessage.getSubject()));
            }
          }
        }
      }
    } catch (Exception e) {
      log.error(e, e);
    }
  } 
  
  /**
   * Method saveAttach()
   * 
   * @param emailMessage
   * @param part
   * @return @throws
   *         Exception
   */
  private void saveAttach(EmailMessageImpl emailMessage,EmailAttachmentImpl emailAttachment) throws Exception {
    emailMessage.addAttachment(emailAttachment);
  }
  
  /**
   * Method close()
   * 
   * @return @throws
   *         Exception
   */
  public void closeStroreAndMailFolder() throws Exception {
    if (folder != null && folder.isOpen()) {
      folder.close(false);
    }
    if (store != null && store.isConnected()) {
      store.close();
    }
  }
  
  /**
   * Method  getFolder
   * @return
   */
  
  public EmailFolder getFolder() {
    return this.folder;
  }
  
  /**
   * Method  parseArrayDataToString
   * @param arrayData
   * @return
   */
  private String parseArrayDataToString(Address[] arrayData) {
    String returnString = "";
    if (arrayData == null) {
      return returnString;
    }
    for (int i = 0; i < arrayData.length; i++) {
      if (i != 0) {
        returnString += ",";
      }
      //returnString += ((InternetAddress)arrayData[i]).getAddress().toString();
      returnString += arrayData[i].toString();
      
    }
    return returnString;
  }
  
  
  /**
   * Method  putAttachToCatchFile
   * @param bodyPart
   * @param sequence
   * @return
   */
  private EmailAttachmentImpl putAttachToCatchFile(BodyPart bodyPart, int sequence,String subject) {
    EmailAttachmentImpl emailAttachment = new EmailAttachmentImpl();
    try {
      long currentTime = new java.util.Date().getTime();
      Random rand = new Random();
      Double randomNum = new Double((Math.random() * 1000));
      String folderName = SystemParameterFactory
      .getSystemParameter(SystemParameterConstant.DMS_EMAILARCHIVE_CACHEFOLDER_PATH);
      File catcheFolder = new File(folderName);
      if (!catcheFolder.exists()) {
        catcheFolder.mkdir();
      }
      String fileName = sessionContainer.getUserRecordID() + "_"
      + currentTime + "_" + randomNum.intValue() + "_" + sequence
      + ".tmp";
      FileOutputStream objfile = new FileOutputStream(folderName
          + fileName);
      InputStream inputStream = bodyPart.getInputStream();
      int bufferSize = 8192;
      byte[] buffer = new byte[bufferSize];
      int length = -1;
      int allLength = 0;
      while ((length = inputStream.read(buffer, 0, bufferSize)) != -1) {
        objfile.write(buffer, 0, length);
      }      
      
      objfile.flush();
      objfile.close();
      if(!Utility.isEmpty(bodyPart.getFileName())){
        emailAttachment.setAttachFileName(decodeText(bodyPart.getFileName()));                
      }else{
//      /**************************************/        
//      Session mailSession = Session.getDefaultInstance(System.getProperties(), null);
//      MimeMessage msg = new MimeMessage(mailSession,bodyPart.getInputStream());
//      EmailMessageImpl emailMessageTest = EmailMessageImpl.newInstance();
//      getMailPriority(emailMessageTest,msg);
//      
//      
//      /**************************************/
        emailAttachment.setAttachFileName(decodeText(subject));        
      }
      emailAttachment.setCatchFileName((fileName));
      emailAttachment.setContentID(((MimePart) bodyPart).getContentID());
      emailAttachment.setFileSize(bodyPart.getSize());
    } catch (Exception e) {
      log.error(e, e);
    }
    return emailAttachment;
  }
  
  /**
   * Method  decodeText
   * @param str
   * @return
   */
  public String decodeText(String str){
    try{
      if(str == null ){
        return "";
      }  
      if ( str.indexOf("=?x-unknown?") >=0 ){
        str = str.replaceAll("x-unknown","gbk"  );
      }
      
      try{
        str = MimeUtility.decodeText( str ); 
      }catch( Exception e1){
        log.error(e1, e1);
        return str ;
      }    
      
    }catch(Exception e){
      log.error(e, e);
      str = "";
    }
    str = decodeTextByEmailEncoding(str);
    return str;
  }
  
  /**
   * Method  formatEmailAdress
   * @param inputStr
   * @return
   * fomat emailAdress string to adress<adress> 
   * emp: xxx@dcivision.com,xxx1@dcivision.com =>  
   * xxx@dcivision.com<xxx@dcivision.com>;xxx1@dcivision.com<xxx1@dcivision.com>   
   */
  
  public String formatEmailAdress(String inputStr){    
    String returnString = "";
    String[] adressArray = new String[0]; 
    if(inputStr == null ){
      return "";
    }      
    inputStr = inputStr.replaceAll("\"",""  );
    // if inputStr include <>,not include "," and ";" ,not need format
    if((inputStr.indexOf(",") != -1 || inputStr.indexOf(";") != -1) 
        && (inputStr.indexOf("<") == -1 && inputStr.indexOf(">") == -1)){
      if(inputStr.indexOf(",") != -1){    
        adressArray = TextUtility.splitString(inputStr,",");              
      }else if(inputStr.indexOf(";") != -1){
        adressArray = TextUtility.splitString(inputStr,";");
      } 
      if (!Utility.isEmpty(adressArray) && adressArray.length > 1){
        //format string
        for(int i = 0; i< adressArray.length ;i++){
          String tmpStr = " "+(adressArray[i]+"<"+adressArray[i]+">");
          if(i!=0){
            tmpStr = ";"+tmpStr;
          }
          returnString = returnString + tmpStr;
        }
      }else{
        returnString  = inputStr ;
      }
    }else{
      returnString  = inputStr ;        
    }
    return returnString;
  }
  
  
  /**
   * getMessageContent
   * @param request
   * @param mailid
   * @return
   * @throws ApplicationException
   */
  
  public EmailMessage getMessageContent(HttpServletRequest request,String mailid,String mailServerType) throws ApplicationException{
    
    EmailMessage emailMessage = null;     
    try {
      List sessEmailList = (List) request.getSession(true).getAttribute("sessEmailList");
      emailMessage = EmailReceiver.getMailByID(sessEmailList, mailid);
      
      EmailReceiver mailReceiver = EmailReceiverFactory.getEmailReceiverInstanceByServerType(sessionContainer,mailServerType);
      EmailFolderImpl folder = (EmailFolderImpl) request.getSession(true).getAttribute("folder");
      
      if (sessEmailList == null || emailMessage == null || folder == null || Utility.isEmpty(emailMessage.getMessageID())) {
        //this.addError(request, "Cookie Expire,please login again.");
        return emailMessage;
      }
      // if the emailMessage is already get the content then not need get
      // the conent again
      if (emailMessage.getAnalyzed()) {
        return emailMessage;
      }
      Message[] msg = null;
      if (!folder.getStore().isConnected()) {
        folder.getStore().connect();
      }
      
      if (!folder.isOpen()) {
        folder.open(EmailFolderImpl.READ_ONLY);
      }
      msg = folder.getMessages();
//      FetchProfile profile = new FetchProfile();
//      profile.add(FetchProfile.Item.ENVELOPE);
//      folder.fetch(msg, profile);
      for (int i = 0; i < msg.length; i++) {
        String messageID = "";
        try{
          messageID = ((MimeMessage)msg[i]).getMessageID();
        }catch(Exception e){
          log.error(e, e);
        }
        log.debug("emailMessage.getMessageID() is "+emailMessage.getMessageID());
        log.debug("((MimeMessage)msg[i]).getMessageID() is "+messageID);
        if (!emailMessage.getMessageID().equals(messageID)) {
          continue;
        }else{
          //create the temporarily fils
          long currentTime = new java.util.Date().getTime();
          Double randomNum = new Double((Math.random() * 1000));
          String folderName = SystemParameterFactory.getSystemParameter(SystemParameterConstant.DMS_EMAILARCHIVE_CACHEFOLDER_PATH);
          File catcheFolder = new File(folderName);
          if (!catcheFolder.exists()) {
            catcheFolder.mkdir();
          }
          String fileName = sessionContainer.getUserRecordID() + "_"+ currentTime + "_" + randomNum.intValue() + ".eml";
          FileOutputStream objfile = new FileOutputStream(folderName + fileName);
          msg[i].writeTo(objfile);
          
          String name = folderName + fileName;
          File file = new File(name);
          objfile.flush();
          objfile.close();
          
          Long sizetep = new Long(file.length());
          
          EmailAttachmentImpl emailAttachment = new EmailAttachmentImpl();
          emailAttachment.setAttachFileName(decodeText(msg[i].getSubject() == null ?"Not Subject": msg[i].getSubject() )+".eml");  
          emailAttachment.setCatchFileName((fileName));
          emailAttachment.setContentID("");
          emailAttachment.setFileSize(sizetep.intValue());
          emailAttachment.setIsOrigEmail(true);
          emailMessage.addAttachment(emailAttachment);
          
          
          
          StringBuffer bodytext = new StringBuffer();
          if (msg[i].isMimeType("TEXT/*")) {
            bodytext.append(decodeTextByEmailEncoding((String) ((Part) msg[i]).getContent()));
            //bodytext.append(new String(((String) ((Part) msg[i]).getContent()).getBytes("iso-8859-1"),"gb2312"));
            emailMessage.setContent(bodytext.toString());
            emailMessage.setOriContent(bodytext.toString() );
            emailMessage.setEmailContentType(EMAIL_CONTENT_TYPE_TXT);
          } else {
            if ((msg[i].isMimeType("multipart/*"))) {
              this.analyseMultipart((EmailMessageImpl)emailMessage, (Multipart) msg[i].getContent());
            }
            if(Utility.isEmpty( emailMessage.getEmailContentType())){
              emailMessage.setEmailContentType(EMAIL_CONTENT_TYPE_HTML);
            }
          }
          // set the message is analyzed
          emailMessage.setAnalyzed(true);
        }
        break;
      }
      
      if (folder.isOpen()) {
        folder.close(true);
      }
      
      if (folder.getStore().isConnected()) {
        folder.getStore().close();
      }
    } catch (Exception e) {
      log.error(e, e);
      throw new ApplicationException(ErrorConstant.COMMON_FATAL_ERROR);
    }
    return emailMessage;        
  }
  
  /**
   * getMessageContentNew
   * @param request
   * @param mailServerType
   * @return
   * @throws ApplicationException
   */
  
  public EmailMessage getMessageContentNew(HttpServletRequest request,EmailMessage emailMessagePass,String mailServerType) throws ApplicationException{
    EmailMessage emailMessage = emailMessagePass;
    try {
      List sessEmailList = (List) request.getSession(true).getAttribute("sessEmailList");
      
      EmailReceiver mailReceiver = EmailReceiverFactory.getEmailReceiverInstanceByServerType(sessionContainer,mailServerType);
      EmailFolderImpl folder = (EmailFolderImpl) request.getSession(true).getAttribute("folder");
      
      if (sessEmailList == null || emailMessage == null || folder == null) {
        //this.addError(request, "Cookie Expire,please login again.");
        return emailMessage;
      }
      // if the emailMessage is already get the content then not need get
      // the conent again
      if (emailMessage.getAnalyzed()) {
        return emailMessage;
      }
      Message[] msg = null;
      if (!folder.isOpen()) {
        folder.open(EmailFolderImpl.READ_ONLY);
      }
      msg = folder.getMessages();
      FetchProfile profile = new FetchProfile();
      profile.add(FetchProfile.Item.ENVELOPE);
      folder.fetch(msg, profile);
      for (int i = 0; i < msg.length; i++) {        
        if (!emailMessage.getMessageID().equals(((MimeMessage)msg[i]).getMessageID())) {
          continue;
        }
        
        //create the temporarily fils
        long currentTime = new java.util.Date().getTime();
        Double randomNum = new Double((Math.random() * 1000));
        String folderName = SystemParameterFactory.getSystemParameter(SystemParameterConstant.DMS_EMAILARCHIVE_CACHEFOLDER_PATH);
        File catcheFolder = new File(folderName);
        if (!catcheFolder.exists()) {
          catcheFolder.mkdir();
        }
        String fileName = sessionContainer.getUserRecordID() + "_"+ currentTime + "_" + randomNum.intValue() + ".eml";
        FileOutputStream objfile = new FileOutputStream(folderName + fileName);
        msg[i].writeTo(objfile);
        
        String name = folderName + fileName;
        File file = new File(name);
        objfile.flush();
        objfile.close();
        
        Long sizetep = new Long(file.length());
        
        EmailAttachmentImpl emailAttachment = new EmailAttachmentImpl();
        emailAttachment.setAttachFileName(msg[i].getSubject()+".eml");  
        emailAttachment.setCatchFileName((fileName));
        emailAttachment.setContentID("");
        emailAttachment.setFileSize(sizetep.intValue());
        emailMessage.addAttachment(emailAttachment);
        
        
        StringBuffer bodytext = new StringBuffer();
        if (msg[i].isMimeType("TEXT/*")) {
          bodytext.append((String) ((Part) msg[i]).getContent());
          String contentText = decodeTextByEmailEncoding(bodytext.toString());  
          emailMessage.setContent(contentText);
          emailMessage.setOriContent(contentText);
          emailMessage.setEmailContentType(EMAIL_CONTENT_TYPE_TXT);
        } else {
          if ((msg[i].isMimeType("multipart/*"))) {
            this.analyseMultipart((EmailMessageImpl)emailMessage, (Multipart) msg[i].getContent());
          }
          if(Utility.isEmpty( emailMessage.getEmailContentType())){
            emailMessage.setEmailContentType(EMAIL_CONTENT_TYPE_HTML);
          }
        }
        // set the message is analyzed
        emailMessage.setAnalyzed(true);
      }
      if (folder.isOpen()) {
        folder.close(true);
      }
    } catch (Exception e) {
      log.error(e, e);
      throw new ApplicationException(ErrorConstant.COMMON_FATAL_ERROR);
    }
    return emailMessage;        
  }
  
  
  /**
   * getMessageContent
   * @param request
   * @param mailid
   * @return
   * @throws ApplicationException
   */
  public EmailMessage getMessageContentByEmailMessge(EmailMessage emailMessage,EmailFolderImpl folder,String mailServerType) throws ApplicationException{       
    try {          
      EmailReceiver mailReceiver = EmailReceiverFactory.getEmailReceiverInstanceByServerType(sessionContainer,mailServerType);          
      Message[] msg = null;
      
      if (!folder.isOpen()) {
        folder.open(EmailFolderImpl.READ_ONLY);
      }
      msg = folder.getMessages();
      FetchProfile profile = new FetchProfile();
      profile.add(FetchProfile.Item.ENVELOPE);
      folder.fetch(msg, profile);
      for (int i = 0; i < msg.length; i++) {
        if (!emailMessage.getMessageID().equals(((MimeMessage)msg[i]).getMessageID())) {
          continue;
        }
        StringBuffer bodytext = new StringBuffer();
        if (msg[i].isMimeType("TEXT/*")) {
          bodytext.append((String) ((Part) msg[i]).getContent());
          String contentText = decodeTextByEmailEncoding(bodytext.toString());  
          emailMessage.setContent(contentText);
          emailMessage.setOriContent(contentText);
          emailMessage.setEmailContentType(EMAIL_CONTENT_TYPE_TXT);
        } else {
          if ((msg[i].isMimeType("multipart/*"))) {
            this.analyseMultipart((EmailMessageImpl)emailMessage, (Multipart) msg[i].getContent());
          }
          if(Utility.isEmpty( emailMessage.getEmailContentType())){
            emailMessage.setEmailContentType(EMAIL_CONTENT_TYPE_HTML);
          }
        }
        // set the message is analyzed
        emailMessage.setAnalyzed(true);
      }
    } catch (Exception e) {
      log.error(e, e);
      throw new ApplicationException(ErrorConstant.COMMON_FATAL_ERROR);
    }
    return emailMessage;        
  }  
  
  
  /**
   * Method loadAndProcessMailList()
   * 
   * @param host
   * @param name
   * @param password
   * @param protocol
   * @return mail list
   * @throws Exception
   */
  
  public List loadAndProcessMailList(String host, String name, String password,String protocol) throws Exception {
    EmailFolderImpl journalingFolder;
    Store journalingStore;    
    int maxEmailNumber = 500 ;    
    List journalingMailList = new ArrayList();
    try {
      Properties prop = System.getProperties();
      Session session = Session.getDefaultInstance(prop, null);
      session.setDebug(false);
      journalingStore = session.getStore(protocol);
      journalingStore.connect(host, name, password);
      journalingFolder = new EmailFolderImpl(journalingStore.getDefaultFolder().getFolder("INBOX"));      
      
      try{
        journalingFolder.open(EmailFolderImpl.READ_WRITE);
      }catch(Exception e){
        journalingFolder.open(EmailFolderImpl.READ_ONLY);
      }
      Message[] msg = journalingFolder.getMessages();
      FetchProfile profile = new FetchProfile();
      profile.add(FetchProfile.Item.ENVELOPE);
      journalingFolder.fetch(msg, profile);      
      
      long startTime = 0;
      startTime = new java.util.Date().getTime();      
      log.debug("**********************Recive email start");
      
      for (int i = 0; i < msg.length; i++) {
        long startSubTime = 0;
        startSubTime = new java.util.Date().getTime();              
        log.debug("**********************Recive email :number is :"+i+" .");
        if(i>maxEmailNumber){
          break;
        }        
        EmailMessageImpl emailMessage = analysemailEmailMessage(msg[i]);
        if(!journalingMailList.contains(emailMessage)){
          journalingMailList.add(emailMessage);         
        }
        //delete the readed msg
        msg[i].setFlag(Flags.Flag.DELETED,true);            
        long endSubTime = 0;
        endSubTime = new java.util.Date().getTime();                      
        log.debug("**********************Recive email :number is :"+i+" need time :"+(endSubTime-startSubTime)+"ms.");        
      }
      long endTime = 0;
      endTime = new java.util.Date().getTime();            
      log.debug("**********************Recive email end");      
      log.debug("**********************Recive email time is :"+(endTime-startTime)+"ms.");            
      try{
        if (journalingFolder != null && journalingFolder.isOpen()) {
          journalingFolder.close(true);
          journalingFolder = null;
        }
        if (journalingStore != null && journalingStore.isConnected()) {
          journalingStore.close();
          journalingStore = null;        
        }   
      }catch(Exception e){
        log.error(e, e);    
      }
    } catch (Exception e) {
      log.error(e, e); 
      throw e;
    }
    if(Utility.isEmpty(journalingMailList)){
      return new ArrayList();
    }else{
      return processJournalingEmailList(journalingMailList);  
    }    
        
  }
  
  
  /**
   * Method analysemailEmailMessage() -- get the eamil attchment (MIME emails)
   * 
   * @param Message
   * @return EmailMessageImpl 
   * @throws Exception
   */
  
  public EmailMessageImpl analysemailEmailMessage(Message msg)throws Exception {
    EmailMessageImpl emailMessage = EmailMessageImpl.newInstance();      
    try {
      getMailPriority(emailMessage, msg);        
      // analyse email content
      StringBuffer bodytext = new StringBuffer();
      if (msg.isMimeType("TEXT/*")) {
        bodytext.append((String) ((Part) msg).getContent());
        String contentText = decodeTextByEmailEncoding(bodytext.toString());  
        emailMessage.setContent(contentText);
        emailMessage.setOriContent(contentText);
        emailMessage.setEmailContentType(EMAIL_CONTENT_TYPE_TXT);
      } else {
        if ((msg.isMimeType("multipart/*"))) {
          this.analyseMultipart(emailMessage, (Multipart) msg.getContent());
        }
        if(Utility.isEmpty( emailMessage.getEmailContentType())){
          emailMessage.setEmailContentType(EMAIL_CONTENT_TYPE_HTML);
        }
      }
    } catch (Exception e) {
      log.error(e, e);
    }
    return emailMessage;    
  } 
  
  /**
   * Method  formatEmailAdress
   * @param inputStr
   * @return
   * get emailAdress string from adress<adress> 
   * emp: 
   * xxx@dcivision.com<xxx@dcivision.com>;xxx1@dcivision.com<xxx1@dcivision.com>   
   * => xxx@dcivision.com,xxx1@dcivision.com 
   */
  
  public static String getEmailAdressStr(String inputStr){
    String returnString = "";
    String[] adressArray = new String[0]; 
    if(inputStr == null ){
      return "";
    }
    // if inputStr include <>,not include "," and ";" ,not need format
    if((inputStr.indexOf(",") != -1 || inputStr.indexOf(";") != -1) 
        && (inputStr.indexOf("<") != -1 && inputStr.indexOf(">") != -1)){
      if(inputStr.indexOf(",") != -1){
        adressArray = TextUtility.splitString(inputStr,",");              
      }else if(inputStr.indexOf(";") != -1){
        adressArray = TextUtility.splitString(inputStr,";");
      }
      if (!Utility.isEmpty(adressArray) && adressArray.length > 1){
        //format string
        for(int i = 0; i< adressArray.length ;i++){
          //drop the <xxx> str;
          String tmpStr = adressArray[i];
          if(inputStr.indexOf(">") != -1 ){
            tmpStr = tmpStr.substring(tmpStr.indexOf("<")+1,tmpStr.length()-1);
          }
          if(i!=0){
            tmpStr = ","+tmpStr;
          }
          tmpStr = tmpStr.replaceAll("\"","" );
          returnString = returnString + tmpStr;
        }
      }else{
        returnString  = inputStr ;
      }
    }else{
      String tmpStr = inputStr;
      if(inputStr.indexOf(">") != -1 ){
        tmpStr = tmpStr.substring(tmpStr.indexOf("<")+1,tmpStr.length()-1);
        tmpStr = tmpStr.replaceAll("\"","" );        
        returnString  = tmpStr ;                
      }else{
        returnString = inputStr;
      }      
      
    }
    return returnString;
  }  
  
  
  public void setEmailCharset(String emailCharset){
    this.emailCharset = emailCharset;    
  }  
  
  /**Method  decodeTextByEmailEncoding
   * @param inputString
   * @return decoded string
   * this method will decode string to utf-8 by the emailEncoding  
   */
  public String decodeTextByEmailEncoding(String inputString){
    String outPutString = "";
    if (!Utility.isEmpty(this.emailCharset)){      
      try{
        String tempString = new String (inputString.getBytes("iso-8859-1"),this.emailCharset);  
        outPutString = tempString; 
      }catch(Exception e){
        outPutString = inputString;
      }
    }else{
      outPutString = inputString;      
    }
    return outPutString;
  }
  
  private List processJournalingEmailList(List emailMessageList){
    List processedEmailList = new ArrayList();
    for(int i = 0; i< emailMessageList.size() ;i++){
      long startSubTime = 0;
      startSubTime = new java.util.Date().getTime();
      try{  
        EmailMessageImpl emailMessage = (EmailMessageImpl)emailMessageList.get(i);
        // check email owner
        String emailContent = emailMessage.getContent().toString();
        //put all email address to emailAddressList from email content 
        int flageBegin = 0;
        int flageEnd = 0;
        List emailAddressList = new ArrayList();
        String emailAddress = "";
        String allEmailAddress =""; 
        //emailContent="<smtp:dmstestuser1@paradm.net>";
        //GET THE ALL EMAIL ADDRESS
        do{
          flageBegin = emailContent.indexOf(GET_JOURNALING_EMAIL_FROM_EMAILCONTENT_FLAGE_BEGIN,flageEnd);
          flageEnd = emailContent.indexOf(GET_JOURNALING_EMAIL_FROM_EMAILCONTENT_FLAGE_END,flageBegin);
          if(flageBegin !=-1 && flageEnd !=-1){
            //if the content is plain text
            //emailAddress = emailContent.substring(flageBegin+6,flageEnd);
//          if the content is html
            emailAddress = emailContent.substring(flageBegin+9,flageEnd);
            if(!emailAddressList.contains(emailAddress)){
              emailAddressList.add(emailAddress);        
              allEmailAddress += emailAddress+",";
            }
          }
        }
        while(flageBegin != -1);      
        
        //GET THE ATTACHMENT ,THE ATTACHMENT IS AN .EML FORMAT FILE
        String catchFileName = "";
        List attachmentList = emailMessage.getAttachments();
        DataInputStream inputStream ;
        EmailMessageImpl emlEmailMessage = null;
        EmailMessageToRule emailMessageToRule = new EmailMessageToRule();
        EmailAttachmentImpl emailAttachment = null;
        if(attachmentList.size() > 0){
          emailAttachment = (EmailAttachmentImpl)attachmentList.get(0); 
          catchFileName = emailAttachment.getCatchFileName();
          //attachFileName = emailAttachment.getAttachFileName();
        }// if the email not have attachment ,then this email is not a journaling email
        else{
          continue;
        }
        String cachePath = SystemParameterFactory.getSystemParameter(SystemParameterConstant.DMS_EMAILARCHIVE_CACHEFOLDER_PATH);            
        String trueFilePath = cachePath + catchFileName;
        File file = new File(trueFilePath);
        if (file.exists()) {
          inputStream = new DataInputStream(new BufferedInputStream(new FileInputStream(trueFilePath)));
          //get the eml from the attachment,the emlEmailMessage is real emailmessage bean
          emailMessage.getAttachments();
          Session mailSession = Session.getDefaultInstance(System.getProperties(), null);
          MimeMessage msg = new MimeMessage(mailSession,inputStream);
          emlEmailMessage =  this.analysemailEmailMessage(msg);           
          inputStream.close();          
        }
        
        inputStream = null;
        file = null;
        if(emlEmailMessage !=null ){        
          //add the eml file at the message's attachment
          if(emailAttachment!=null){
            String attachFileName = emailAttachment.getAttachFileName();  
            if(attachFileName.indexOf(".eml") == -1){
              attachFileName = attachFileName +".eml";                
            }
            emailAttachment.setAttachFileName(attachFileName);
            emailAttachment.setIsOrigEmail(true);
            emlEmailMessage.addAttachment(emailAttachment);                     
          }        
          processedEmailList.add(emlEmailMessage);
        }
      } catch (Exception e) {
        log.error(e, e);
      }      
    }       
    
    return processedEmailList;
    
  }
  
  
  
}